package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
import com.heima.common.constants.message.WmNewsUpDownConstants;
import com.heima.common.dtos.PageResult;
import com.heima.common.dtos.ResponseResult;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.threadlocal.UserThreadLocalUtils;
import com.heima.common.util.BeanHelper;
import com.heima.common.util.JsonUtils;
import com.heima.model.admin.dtos.NewsAuthDto;
import com.heima.model.media.dtos.WmNewsDto;
import com.heima.model.media.dtos.WmNewsPageReqDto;
import com.heima.model.media.dtos.WmNewsResultDTO;
import com.heima.wemedia.entity.WmMaterial;
import com.heima.wemedia.entity.WmNews;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.wemedia.service.WmMaterialService;
import com.heima.wemedia.service.WmNewsAuditService;
import com.heima.wemedia.service.WmNewsMaterialService;
import com.heima.wemedia.service.WmNewsService;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.heima.common.constants.message.Article2EsConstants.ES_DELETE_ARTICLE_TOPIC;
import static com.heima.common.constants.message.WmNewsUpDownConstants.*;

/**
 * <p>
 * 自媒体图文内容信息表 服务实现类
 * </p>
 *
 * @author RMY
 * @since 2021-11-24
 */
@Service
@Slf4j
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
    @Autowired
    private WmNewsMaterialService wmNewsMaterialService;
    @Autowired
    private WmNewsAuditService wmNewsAuditService;
    /**
     * 查询所有文章
     * @param dto
     * @return
     */
    @Override
    public PageResult<WmNewsResultDTO> findByPage(WmNewsPageReqDto dto) {
        //1.获取用户Id
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId == null || userId == 0){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //设置分页
        IPage<WmNews> iPage = new Page<>(dto.getPage(), dto.getSize());
        //创建查询条件
        QueryWrapper<WmNews> qw = new QueryWrapper<>();
        qw.lambda().eq(WmNews::getWmUserId,userId);
        if (dto.getStatus() != null && dto.getStatus() != -1){
            if (dto.getStatus() == 1){
                qw.lambda().in(WmNews::getStatus,new Integer[]{1,3});
            }
            else if (dto.getStatus() == 4){
                qw.lambda().in(WmNews::getStatus,new Integer[]{4,8,9});
            }
            else {
                qw.lambda().eq(WmNews::getStatus,dto.getStatus());
            }
        }
        if (dto.getChannelId() != null){
            qw.lambda().eq(WmNews::getChannelId,dto.getChannelId());
        }
        if (StringUtils.isNotBlank(dto.getKeyword())){
            qw.lambda().like(WmNews::getTitle,dto.getKeyword());
        }
        if (dto.getBeginPubDate()!=null){
            qw.lambda().ge(WmNews::getPublishTime,dto.getBeginPubDate());
        }
        if (dto.getEndPubDate()!=null){
            qw.lambda().le(WmNews::getPublishTime,dto.getEndPubDate());
        }
        //分页查询
        IPage<WmNews> page = this.page(iPage, qw);
        //判断
        if (page == null || CollectionUtils.isEmpty(page.getRecords())){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //返回
        return new PageResult(dto.getPage(),dto.getSize(),page.getTotal(), BeanHelper.copyWithCollection(iPage.getRecords(),WmNewsResultDTO.class));
    }
    /**
     * 文章新增修改提交
     * @param dto
     * @return
     */
    @Override
    public void submit(WmNewsDto dto) {
        //1.获取用户Id
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId == null|| userId ==0){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //封装Wmnews
        WmNews wmNews = BeanHelper.copyProperties(dto, WmNews.class);
        wmNews.setWmUserId(userId);
        wmNews.setCreatedTime(new Date());
        wmNews.setEnable(true);
        //处理封面图片
        List<String> images = dto.getImages();
        if (CollectionUtils.isNotEmpty(images)){
            String imageStr = images.stream().collect(Collectors.joining(","));
            wmNews.setImages(imageStr);
        }
        //分析状态设置提交时间
        if (dto.getStatus() == 0){
            wmNews.setSubmitedTime(null);
        }else {
            wmNews.setSubmitedTime(new Date());
        }
        //保存或修改文章
        boolean b = save(wmNews);
        if (!b){
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
        }
        //获取自媒体文章id
        Integer wmNewsId = wmNews.getWmUserId();
        //修改wmNews，则删除中间表
        if (dto.getId()!=null){
            wmNewsMaterialService.removeById(wmNewsId);
        }
        //保存中间表（封面素材）
        if (CollectionUtils.isNotEmpty(dto.getImages())){
            List<Integer> imageIds = handlerImage(dto.getImages());
            //保存
            wmNewsMaterialService.saveBatchByNewsIdAndImageIds(wmNewsId,imageIds,1);
        }
        //保存中间表（内容）
        if (dto.getContent()!=null){
            List<Integer> contentImages = handlerContentImage(dto.getContent());
            wmNewsMaterialService.saveBatchByNewsIdAndImageIds(wmNewsId,contentImages,0);
        }
        //       如果是提交审核 异步审核文章内容
        if(!dto.getDraft()) {
            wmNewsAuditService.auditWmNews(wmNews.getId());
        }
    }
    @Autowired
    private KafkaTemplate kafkaTemplate;

    /**
     * 上架或下架
     * @param dto
     * @return
     */
    @Override
    public void downOrUp(WmNewsDto dto) {
        //获取用户Id
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId == null || userId == 0){
            //抛异常
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据用户id及文章Id查出文章
        QueryWrapper<WmNews> qw = new QueryWrapper<>();
        qw.lambda().eq(WmNews::getId,dto.getId()).eq(WmNews::getWmUserId,userId);
        //查询
        WmNews wmNews = getOne(qw);
        if (wmNews == null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //如果文章状态不是上架状态，则抛出异常
        if (wmNews.getStatus()!=9){
            throw new LeadException(AppHttpCodeEnum.PARAM_INVALID);
        }
        //如果前端传的和数据库一直，则不改 0-下架   目前上架的都是-1
        if(dto.getEnable().equals(wmNews.getEnable())){
            return;
        }
        //修改
        UpdateWrapper<WmNews> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(WmNews::getId,dto.getId()).set(WmNews::getEnable,dto.getEnable());
        update(updateWrapper);

        //构造消息内容
        Map<String,Long> map = new HashMap<>();
        map.put("articleId",dto.getArticleId());
        map.put("enable",dto.getEnable()?1L:0L);
        //发送kafka
        String msg = JsonUtils.toString(map);
        log.info("kafka要发送的信息"+msg);
        kafkaTemplate.send(WM_NEWS_UP_OR_DOWN_TOPIC,msg);
    }

    /**
     * 根据id查询文章
     * */
//    @Override
//    public WmNews findByid(Integer id) {
//        //id查询文章内容ii
//        WmNews wmNews = getById(id);
//        //判断是否有文章
//        if (wmNews == null){
//            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
//        }
//        //如果文章状态不是上架状态，则抛出异常
//        if (wmNews.getStatus()!=9){
//            throw new LeadException(AppHttpCodeEnum.PARAM_INVALID);
//        }
//        return wmNews;
//    }
    /**
     * 删除自媒体文章
     * */
    @Override
    public void deleteById(Integer id) {
        //查询
        WmNews wmNews = getById(id);

        if (wmNews==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //删除自媒体文章
        boolean b = removeById(id);
        //删除
        if (!b){
            throw new LeadException(AppHttpCodeEnum.UPDATE_ERROR);
        }

       kafkaTemplate.send(ES_DELETE_ARTICLE_TOPIC,wmNews.getArticleId().toString());
    }

    /**
     * 分页查找自媒体文章
     * @param dto
     * @return
     */
    @Override
    public PageResult<WmNewsResultDTO> findByPageAndTitle(NewsAuthDto dto) {
        //设置分页
        IPage<WmNews> iPage = new Page<>(dto.getPage(), dto.getSize());
        //创建查询条件
        QueryWrapper<WmNews> qw = new QueryWrapper<>();
        if (dto.getTitle()!=null){
            qw.lambda().like(WmNews::getTitle,dto.getTitle());
        }
        IPage<WmNews> page = this.page(iPage, qw);
        //返回
        return new PageResult(dto.getPage(),dto.getSize(),page.getTotal(), BeanHelper.copyWithCollection(iPage.getRecords(),WmNewsResultDTO.class));
    }

    /**
     * 通过id查找自媒体文章
     * @param newsId
     * @return
     */
    @Override
    public WmNewsResultDTO findById(Integer newsId) {
        WmNews byId = this.getById(newsId);
        WmNewsResultDTO wmNewsResultDTO = BeanHelper.copyProperties(byId, WmNewsResultDTO.class);
        return wmNewsResultDTO;
    }

    /**
     * 自媒体文章审核不通过
     * @param dto
     */
    @Override
    public void authFail(NewsAuthDto dto) {
        if (dto.getMsg()==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //查找自媒体文章
        WmNews wmNews = this.getById(dto.getId());
        //修改状态，更新reason
        wmNews.setStatus(2);
        wmNews.setReason(dto.getMsg());
        this.saveOrUpdate(wmNews);
    }

    /**
     * 自媒体文章人工审核通过
     * @param dto
     */
    @Override
    public void authPass(NewsAuthDto dto) {
        //查找自媒体文章
        WmNews wmNews = this.getById(dto.getId());
        //修改状态
        wmNews.setStatus(4);
        this.saveOrUpdate(wmNews);
    }


    /**
     * 分页查询和搜索
     * @param
     * @param title
     * @return
     */

    /**
     * 处理接受的内容，获得图片素材的id
     * @param images
     * @return
     */
    @Autowired
    private WmMaterialService wmMaterialService;
    private List<Integer> handlerImage(List<String> images){
        //1.创建查询对象
        QueryWrapper<WmMaterial> qw = new QueryWrapper<>();
        qw.lambda().in(WmMaterial::getUrl,images);
        List<WmMaterial> list = wmMaterialService.list(qw);
        //封装list中的id
        List<Integer> ids = list.stream().map(WmMaterial::getId).collect(Collectors.toList());
        //3.返回
        return ids;
    }

    /**
     * 处理content中的素材id
     * @param content
     * @return
     */
    private List<Integer> handlerContentImage(String content){
        List<Integer> ids = new ArrayList<>();
        //将content转换为List<Map<String,Object>>
        List<Map<String, Object>> list = JsonUtils.nativeRead(content, new TypeReference<List<Map<String, Object>>>() {
        });
        //遍历List，去处素材id
        for (Map<String, Object> map : list) {
            if ("image".equals(map.get("type").toString())){
                //取出素材Id
                Integer materialId = Integer.valueOf(map.get("id").toString());
                ids.add(materialId);
            }
        }
        return ids;
    }


}
